package com.cpems.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cpems.system.domain.*;
// import com.cpems.system.domain.enums.TopicType; // 已注释，因为TopicType类已被禁用
import com.cpems.system.mapper.*;
import com.cpems.system.service.IDataProcessingService;
import com.cpems.system.service.IRealtimeAlarmService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 数据处理服务实现类
 * 用于替代RabbitMQ的数据处理逻辑，直接从MySQL拉取数据进行处理
 *
 * @author cpems
 * @date 2023-12-01
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DataProcessingServiceImpl implements IDataProcessingService {

    private final ElectricityUMapper electricityUMapper;
    private final ElectricityIMapper electricityIMapper;
    private final ElectricityPMapper electricityPMapper;
    private final ElectricityWMapper electricityWMapper;
    private final WaterConsumptionMapper waterConsumptionMapper;
    private final IRealtimeAlarmService realtimeAlarmService;

    @Override
    @Transactional
    public void processUnprocessedElectricityU() {
        log.info("开始处理未处理的电压数据");
        
        // 查询最近5分钟内的未处理数据
        Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
        LambdaQueryWrapper<ElectricityU> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(ElectricityU::getCreateTime, fiveMinutesAgo)
               .orderByAsc(ElectricityU::getCreateTime);
        
        List<ElectricityU> unprocessedData = electricityUMapper.selectList(wrapper);
        
        for (ElectricityU data : unprocessedData) {
            try {
                // processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_U); // 已注释，因为TopicType类已被禁用
                log.info("处理电压数据: clientId={}, value={}", data.getClientId(), data.getValue());
                log.debug("处理电压数据成功: clientId={}, value={}", data.getClientId(), data.getValue());
            } catch (Exception e) {
                log.error("处理电压数据失败: clientId={}, value={}, error={}", 
                         data.getClientId(), data.getValue(), e.getMessage(), e);
            }
        }
        
        log.info("电压数据处理完成，共处理 {} 条记录", unprocessedData.size());
    }

    @Override
    @Transactional
    public void processUnprocessedElectricityI() {
        log.info("开始处理未处理的电流数据");
        
        Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
        LambdaQueryWrapper<ElectricityI> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(ElectricityI::getCreateTime, fiveMinutesAgo)
               .orderByAsc(ElectricityI::getCreateTime);
        
        List<ElectricityI> unprocessedData = electricityIMapper.selectList(wrapper);
        
        for (ElectricityI data : unprocessedData) {
            try {
                // processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_I); // 已注释，因为TopicType类已被禁用
                log.info("处理电流数据: clientId={}, value={}", data.getClientId(), data.getValue());
                log.debug("处理电流数据成功: clientId={}, value={}", data.getClientId(), data.getValue());
            } catch (Exception e) {
                log.error("处理电流数据失败: clientId={}, value={}, error={}", 
                         data.getClientId(), data.getValue(), e.getMessage(), e);
            }
        }
        
        log.info("电流数据处理完成，共处理 {} 条记录", unprocessedData.size());
    }

    @Override
    @Transactional
    public void processUnprocessedElectricityP() {
        log.info("开始处理未处理的电功率数据");
        
        Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
        LambdaQueryWrapper<ElectricityP> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(ElectricityP::getCreateTime, fiveMinutesAgo)
               .orderByAsc(ElectricityP::getCreateTime);
        
        List<ElectricityP> unprocessedData = electricityPMapper.selectList(wrapper);
        
        for (ElectricityP data : unprocessedData) {
            try {
                // processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_P); // 已注释，因为TopicType类已被禁用
                log.info("处理功率数据: clientId={}, value={}", data.getClientId(), data.getValue());
                log.debug("处理电功率数据成功: clientId={}, value={}", data.getClientId(), data.getValue());
            } catch (Exception e) {
                log.error("处理电功率数据失败: clientId={}, value={}, error={}", 
                         data.getClientId(), data.getValue(), e.getMessage(), e);
            }
        }
        
        log.info("电功率数据处理完成，共处理 {} 条记录", unprocessedData.size());
    }

    @Override
    @Transactional
    public void processUnprocessedElectricityW() {
        log.info("开始处理未处理的总用电量数据");
        
        Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
        LambdaQueryWrapper<ElectricityW> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(ElectricityW::getCreateTime, fiveMinutesAgo)
               .orderByAsc(ElectricityW::getCreateTime);
        
        List<ElectricityW> unprocessedData = electricityWMapper.selectList(wrapper);
        
        for (ElectricityW data : unprocessedData) {
            try {
                // processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_W); // 已注释，因为TopicType类已被禁用
                log.info("处理用电量数据: clientId={}, value={}", data.getClientId(), data.getValue());
                log.debug("处理总用电量数据成功: clientId={}, value={}", data.getClientId(), data.getValue());
            } catch (Exception e) {
                log.error("处理总用电量数据失败: clientId={}, value={}, error={}", 
                         data.getClientId(), data.getValue(), e.getMessage(), e);
            }
        }
        
        log.info("总用电量数据处理完成，共处理 {} 条记录", unprocessedData.size());
    }

    @Override
    @Transactional
    public void processUnprocessedWaterConsumption() {
        log.info("开始处理未处理的用水量数据");
        
        Date fiveMinutesAgo = new Date(System.currentTimeMillis() - 5 * 60 * 1000);
        LambdaQueryWrapper<WaterConsumption> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(WaterConsumption::getCreateTime, fiveMinutesAgo)
               .orderByAsc(WaterConsumption::getCreateTime);
        
        List<WaterConsumption> unprocessedData = waterConsumptionMapper.selectList(wrapper);
        
        for (WaterConsumption data : unprocessedData) {
            try {
                processWaterData(data.getClientId(), data.getValue());
                log.debug("处理用水量数据成功: clientId={}, value={}", data.getClientId(), data.getValue());
            } catch (Exception e) {
                log.error("处理用水量数据失败: clientId={}, value={}, error={}", 
                         data.getClientId(), data.getValue(), e.getMessage(), e);
            }
        }
        
        log.info("用水量数据处理完成，共处理 {} 条记录", unprocessedData.size());
    }

    /*
    // 已注释，因为TopicType类已被禁用
    @Override
    public void processDataByType(TopicType topicType) {
        log.info("开始处理指定类型数据: {}", topicType);
        
        switch (topicType) {
            case ELECTRIC_U:
                processUnprocessedElectricityU();
                break;
            case ELECTRIC_I:
                processUnprocessedElectricityI();
                break;
            case ELECTRIC_P:
                processUnprocessedElectricityP();
                break;
            case ELECTRIC_W:
                processUnprocessedElectricityW();
                break;
            case WATER_CONSUMPTION:
                processUnprocessedWaterConsumption();
                break;
            default:
                log.warn("未知的数据类型: {}", topicType);
                break;
        }
        
        log.info("指定类型数据处理完成: {}", topicType);
    }
    */

    @Override
    public void processAllUnprocessedData() {
        log.info("开始处理所有未处理的数据");
        
        try {
            processUnprocessedElectricityU();
            processUnprocessedElectricityI();
            processUnprocessedElectricityP();
            processUnprocessedElectricityW();
            processUnprocessedWaterConsumption();
            
            log.info("所有未处理数据处理完成");
        } catch (Exception e) {
            log.error("处理未处理数据时发生错误", e);
            throw e;
        }
    }

    /*
    // 已注释，因为TopicType类已被禁用
    @Override
    public void processDeviceData(String clientId, TopicType topicType) {
        log.info("开始处理指定设备数据: clientId={}, topicType={}", clientId, topicType);
        
        try {
            switch (topicType) {
                case ELECTRIC_U:
                    List<ElectricityU> uData = electricityUMapper.selectList(
                        new LambdaQueryWrapper<ElectricityU>()
                            .eq(ElectricityU::getClientId, clientId)
                            .eq(ElectricityU::getIsProcessed, 0)
                    );
                    uData.forEach(data -> processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_U));
                    break;
                    
                case ELECTRIC_I:
                    List<ElectricityI> iData = electricityIMapper.selectList(
                        new LambdaQueryWrapper<ElectricityI>()
                            .eq(ElectricityI::getClientId, clientId)
                            .eq(ElectricityI::getIsProcessed, 0)
                    );
                    iData.forEach(data -> processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_I));
                    break;
                    
                case ELECTRIC_P:
                    List<ElectricityP> pData = electricityPMapper.selectList(
                        new LambdaQueryWrapper<ElectricityP>()
                            .eq(ElectricityP::getClientId, clientId)
                            .eq(ElectricityP::getIsProcessed, 0)
                    );
                    pData.forEach(data -> processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_P));
                    break;
                    
                case ELECTRIC_W:
                    List<ElectricityW> wData = electricityWMapper.selectList(
                        new LambdaQueryWrapper<ElectricityW>()
                            .eq(ElectricityW::getClientId, clientId)
                            .eq(ElectricityW::getIsProcessed, 0)
                    );
                    wData.forEach(data -> processElectricityData(data.getClientId(), data.getValue(), TopicType.ELECTRIC_W));
                    break;
                    
                case WATER_CONSUMPTION:
                    // 处理水消费数据
                    break;
                    
                default:
                    log.warn("未知的数据类型: {}", topicType);
                    break;
            }
        } catch (Exception e) {
            log.error("处理指定设备数据失败: clientId={}, topicType={}", clientId, topicType, e);
        }
        
        log.info("指定设备数据处理完成: clientId={}, topicType={}", clientId, topicType);
    }
    */

    /*
    // 已注释，因为TopicType类已被禁用
    private void processElectricityData(String clientId, BigDecimal value, TopicType topicType) {
        try {
            log.info("处理电力数据: clientId={}, value={}, topicType={}", clientId, value, topicType);
            realtimeAlarmService.processDeviceData(clientId, value, topicType);
        } catch (Exception e) {
            log.error("处理电力数据失败: clientId={}, value={}, topicType={}",
                    clientId, value, topicType, e);
        }
    }
    */

    /**
     * 处理用水量数据
     */
    private void processWaterData(String clientId, BigDecimal value) {
        try {
            // 调用实时报警服务进行数据处理和报警检查
            // realtimeAlarmService.processDeviceData(clientId, value, TopicType.WATER_CONSUMPTION); // 已注释，因为TopicType类已被禁用
            log.info("处理水消费数据: clientId={}, value={}", clientId, value);
        } catch (Exception e) {
            log.error("处理用水量数据失败: clientId={}, value={}", clientId, value, e);
            throw e;
        }
    }
}